\CUSDependency{ package={geometry,graphicx} }
\CUSProvideExplModule{bgfg}{\cus@d@te}{\cus@versi@n}{background and foreground}

\box_new:N \l__cus_bgfg_box 
\cs_generate_variant:Nn \hook_gput_code:nnn { nne }
\cs_generate_variant:Nn \hook_gput_next_code:nn { ne }

\cs_new_protected:Npn \__cus_bfground_lt:n #1
  {
    \hbox_set:Nn \l__cus_bgfg_box { \hbox_overlap_right:n {#1} }
    \put (\Gm@layouthoffset,-\Gm@layoutvoffset) 
      { \vbox_to_zero:n { \box_use_drop:N \l__cus_bgfg_box \tex_vss:D } }
  }
\cs_new_protected:Npn \__cus_bfground_ct:n #1
  {
    \hbox_set:Nn \l__cus_bgfg_box { \hbox_overlap_center:n {#1} }
    \put (\Gm@layouthoffset+.5\Gm@layoutwidth,-\Gm@layoutvoffset)
      { \vbox_to_zero:n { \box_use_drop:N \l__cus_bgfg_box \tex_vss:D } }
  }
\cs_new_protected:Npn \__cus_bfground_rt:n #1
  {
    \hbox_set_to_wd:Nnn \l__cus_bgfg_box { \Gm@layoutwidth } { \tex_hss:D #1 }
    \put (\Gm@layouthoffset,-\Gm@layoutvoffset) 
      { \vbox_to_zero:n { \box_use_drop:N \l__cus_bgfg_box \tex_vss:D } }
  }
\cs_new_protected:Npn \__cus_bfground_lb:n #1
  {
    \hbox_set:Nn \l__cus_bgfg_box { \hbox_overlap_right:n {#1} }
    \put (\Gm@layouthoffset,-\Gm@layoutvoffset-\Gm@layoutheight)
      {
        \hbox:n 
          {
            \box_move_up:nn { \box_dp:N \l__cus_bgfg_box } 
              { \box_use_drop:N \l__cus_bgfg_box } 
          }
      }
  }
\cs_new_protected:Npn \__cus_bfground_cb:n #1
  {
    \hbox_set:Nn \l__cus_bgfg_box { \hbox_overlap_center:n {#1} }
    \put (\Gm@layouthoffset+.5\Gm@layoutwidth,-\Gm@layoutvoffset-\Gm@layoutheight)
      {
        \hbox:n 
          {
            \box_move_up:nn { \box_dp:N \l__cus_bgfg_box }
              { \box_use_drop:N \l__cus_bgfg_box }
          }
      }
  }
\cs_new_protected:Npn \__cus_bfground_rb:n #1
  {
    \hbox_set_to_wd:Nnn \l__cus_bgfg_box { \Gm@layoutwidth } { \tex_hss:D #1 }
    \put (\Gm@layouthoffset,-\Gm@layoutvoffset-\Gm@layoutheight)
      {
        \hbox:n 
          {
            \box_move_up:nn { \box_dp:N \l__cus_bgfg_box }
              { \box_use_drop:N \l__cus_bgfg_box }
          }
      }
  }
\cs_new_protected:Npn \__cus_bfground_lm:n #1
  {
    \hbox_set:Nn \l__cus_bgfg_box { \hbox_overlap_right:n {#1} }
    \put (\Gm@layouthoffset,
      {-\Gm@layoutvoffset-.5\Gm@layoutheight-.5\box_ht:N \l__cus_bgfg_box+.5\box_dp:N \l__cus_bgfg_box})
      { \vbox:n { \box_use_drop:N \l__cus_bgfg_box } }
  }
\cs_new_protected:Npn \__cus_bfground_cm:n #1
  {
    \hbox_set:Nn \l__cus_bgfg_box { \hbox_overlap_center:n {#1} }
    \put ({\Gm@layouthoffset+.5\Gm@layoutwidth} ,
          {-\Gm@layoutvoffset-.5\Gm@layoutheight-.5\box_ht:N \l__cus_bgfg_box+.5\box_dp:N \l__cus_bgfg_box} )
      { \vbox:n { \box_use_drop:N \l__cus_bgfg_box } }
  }
\cs_new_protected:Npn \__cus_bfground_rm:n #1
  {
    \hbox_set_to_wd:Nnn \l__cus_bgfg_box { \Gm@layoutwidth } { \tex_hss:D #1 }
    \put (\Gm@layouthoffset,
      {-\Gm@layoutvoffset-.5\Gm@layoutheight-.5\box_ht:N \l__cus_bgfg_box+.5\box_dp:N \l__cus_bgfg_box})
      { \vbox:n { \box_use_drop:N \l__cus_bgfg_box } }
  }
\cs_new_protected:Npn \__cus_bfground_ot:n 
  {
    \legacy_if:nTF { @twoside }
      {
        \if_int_odd:w \c@page 
          \exp_after:wN \__cus_bfground_rt:n
        \else:
          \exp_after:wN \__cus_bfground_lt:n
        \fi
      }
      { \__cus_bfground_rt:n }
  }
\cs_new_protected:Npn \__cus_bfground_it:n 
  {
    \legacy_if:nTF { @twoside }
      {
        \if_int_odd:w \c@page 
          \exp_after:wN \__cus_bfground_lt:n
        \else:
          \exp_after:wN \__cus_bfground_rt:n
        \fi
      }
      { \__cus_bfground_lt:n }
  }
\cs_new_protected:Npn \__cus_bfground_im:n 
  {
    \legacy_if:nTF { @twoside }
      {
        \if_int_odd:w \c@page 
          \exp_after:wN \__cus_bfground_lm:n
        \else:
          \exp_after:wN \__cus_bfground_rm:n
        \fi
      }
      { \__cus_bfground_lm:n }
  }
\cs_new_protected:Npn \__cus_bfground_om:n 
  {
    \legacy_if:nTF { @twoside }
      {
        \if_int_odd:w \c@page 
          \exp_after:wN \__cus_bfground_rm:n
        \else:
          \exp_after:wN \__cus_bfground_lm:n
        \fi
      }
      { \__cus_bfground_rm:n }
  }
\cs_new_protected:Npn \__cus_bfground_ib:n 
  {
    \legacy_if:nTF { @twoside }
      {
        \if_int_odd:w \c@page 
          \exp_after:wN \__cus_bfground_lb:n
        \else:
          \exp_after:wN \__cus_bfground_rb:n
        \fi
      }
      { \__cus_bfground_lb:n }
  }
\cs_new_protected:Npn \__cus_bfground_ob:n 
  {
    \legacy_if:nTF { @twoside }
      {
        \if_int_odd:w \c@page 
          \exp_after:wN \__cus_bfground_lb:n
        \else:
          \exp_after:wN \__cus_bfground_rb:n
        \fi
      }
      { \__cus_bfground_lb:n }
  }
\cs_new_protected:Npn \__cus_bfground_:n #1 {#1}
\cs_new_eq:cN { __cus_bfground_~:n } \__cus_bfground_:n 
%%t #1: + : all; no + : next shipout
%%D (#2){lt}: position, lt, lb, rt, rb, it, ib, ot, ob, cm; l: left, r: right, i: inner, o: outer, t: top, b: bottom, c: center, m: middle
%%O [#3]{./fg}: hook label
%%D (#4){}: #2
%%+m #5: code (long)
\ekeysdeclarecmd \foreground { t+ #W{ [] () }{ {./fg} {cm} } m }
  {
    \exp_args:Nno \__cus_expanded:w 
      {
        \bool_if:NTF #1
          { \hook_gput_code:nnn { shipout/foreground } {#2} }
          { \hook_gput_next_code:nn { shipout/foreground }  }
      }
      { \cs:w __cus_bfground_ #3 :n \cs_end: {#4} }
  }
\ekeysdeclarecmd \background { t+ #W{ [] () }{ {./fg} {cm} } m }
  {
    \exp_args:Nno \__cus_expanded:w 
      {
        \bool_if:NTF #1
          { \hook_gput_code:nnn { shipout/background } {#2} }
          { \hook_gput_next_code:nn { shipout/background }  }
      }
      { \cs:w __cus_bfground_ #3 :n \cs_end: {#4} }
  }

%%t #1: + : all; no + : next shipout
%%s #2: * : fit width ; no * : fill page
%%D (#3){lt}: position, lt, lb, rt, rb, it, ib, ot, ob, cm; l: left, r: right, i: inner, o: outer, t: top, b: bottom, c: center, m: middle
%%O [#4]{./bgpic}: hook label
%%D (#5){}: #3
%%m #6: graphics filename
\ekeysdeclarecmd \backgroundpicture { &t+ s #W{ [] [] () } { {} {./bgpic} {lt} } m }
  { 
    \exp_args:Nne \use:n 
      { \background #1 [{#4}] ({#5}) }
      {
        \exp_not:N \includegraphics 
        \bool_if:NTF #2
          { [ width  = \Gm@layoutwidth , \exp_not:n {#3} ] }
          {
            [
              keepaspectratio = false ,
              width  = \Gm@layoutwidth ,
              height = \Gm@layoutheight,
              \exp_not:n {#3}
            ]
          }
          { \exp_not:n {#6} }
      }
  }
\ekeysdeclarecmd \foregroundpicture { &t+ s #W{ [] [] () } { {} {./bgpic} {lt} } m }
  { 
    \exp_args:Nne \use:n 
      { \foreground #1 [{#4}] ({#5}) }
      {
        \exp_not:N \includegraphics 
        \bool_if:NTF #2
          { [ width  = \Gm@layoutwidth , \exp_not:n {#3} ] }
          {
            [
              keepaspectratio = false ,
              width  = \Gm@layoutwidth ,
              height = \Gm@layoutheight ,
              \exp_not:n {#3}
            ]
          }
          { \exp_not:n {#6} }
      }
  }

\ekeysdeclarecmd \removeforeground { } { \RemoveFromHook { shipout/foreground } }
\ekeysdeclarecmd \removebackground { } { \RemoveFromHook { shipout/background } }
